
object = {}

function object:create(cfg)
    local obj = {[-1] = {}, [-2]={}, ["__cfg"] = cfg}
    setmetatable(obj,  { __index = self })

    local base_attr = cfg.attributes.base_attr
    if base_attr then
        for k,v in pairs(base_attr) do
            obj:reg_base_attr(k,v)
        end
    end
    local temp_attr = cfg.attributes.temp_attr
    if temp_attr then
        for k,v in pairs(temp_attr) do
            obj:reg_temp_attr(k,v)
        end
    end
    local runtime_attr = cfg.attributes.runtime_attr
    if runtime_attr then
        for k,v in pairs(runtime_attr) do
            obj:reg_runtime_attr(k,v)
        end
    end
    return obj
end

function object:get_calc_function(key, info)
    if info.formula then
        local formula = info.formula
        return function(self)
            local ok,value = pcall(formula, self)
            return value
        end
    elseif info.table_name and info.table_ukey then
        local tbl_name = info.table_name
        local tbl_ukey = info.table_ukey
        local tbl = self.__cfg.config[tbl_name]
        return function(self)
            local ukey = self["get_"..tbl_ukey](self)
            local value = tbl[ukey][key]
            return value
        end
    else
        local value = info.const
        return function(self)
            return value
        end
    end
end

function object:reg_attr(key, info, idx)
    idx = idx or -1
    self["calc_"..key] = self:get_calc_function(key, info)
    self["get_"..key] = function(self)
        if self[idx][key] then
            return self[idx][key]
        end
        local value = self["calc_"..key](self)
        self[ "set_"..key](self, value)
        return value
    end
    self[ "set_"..key] = function(self, value)
		self[idx][key] = value
	end
end

function object:reg_base_attr(key, info)
    self:reg_attr(key, info, -1)
end

function object:reg_temp_attr(key, info)
    self:reg_attr(key, info, -2)
end

function object:reg_runtime_attr(key, info)
    self["calc_"..key] = self:get_calc_function(key, info)
    self["get_"..key] = function(self)
        local value = self["calc_"..key](self)
        return value
    end
end

return object